package com.effectiveui.away3d.container{
	
	import away3d.cameras.Camera3D;
	import away3d.containers.Scene3D;
	import away3d.containers.View3D;
	import away3d.core.base.Vertex;
	import away3d.core.math.Number3D;
	import away3d.primitives.LineSegment;
	import away3d.primitives.WirePlane;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.geom.Rectangle;
	
	import mx.containers.Canvas;
	import mx.core.ScrollPolicy;
	import mx.events.FlexEvent;

	public class View3D extends Canvas{
		private var _view:away3d.containers.View3D;
		private var _autoRender:Boolean = false;
		private var _showGrid:Boolean = false;
		private var _lookAt:Number3D = new Number3D(0,0,0);

		//debug
		private var wire:WirePlane;
		private var vline:LineSegment;
		private var hline:LineSegment;
		private var gridComplete:Boolean = false;
				
		public function render():void{		
			if(this._view.stage){
				this._view.render();
			}else{
				this.callLater(this.render);
			}
		} 
		
		public function get scene():Scene3D{
			return this._view.scene;
		}
		
		public function set scene(value:Scene3D):void{
			this._view.scene = value;
		}
		
		public function get camera():Camera3D{
			return this._view.camera;
		}
		
		public function set camera(value:Camera3D):void{
			this._view.camera = value;
		}
		
		public function get view():away3d.containers.View3D{
			return this._view;
		}
		
		public function set view(value:away3d.containers.View3D):void{
			//Not needed and allowed;
		}
		
		public function get autoRender():Boolean{
			return this._autoRender;
		}
		
		public function set autoRender(value:Boolean):void{
			this._autoRender = value;
		}
		
		public function get cameraX():Number{
			return this.view.camera.x;
		}
		
		public function set cameraX(value:Number):void{
			this.view.camera.x = value;
			this.view.camera.lookAt(lookAt);
			this.render();
		}
		
		public function get cameraY():Number{
			return this.view.camera.y;
		}
		
		public function set cameraY(value:Number):void{
			this.view.camera.y = value;
			this.view.camera.lookAt(lookAt);
			this.render();
		}
		
		public function get cameraZ():Number{
			return this.view.camera.z;
		}
		
		public function set cameraZ(value:Number):void{
			this.view.camera.z = value;
			this.view.camera.lookAt(lookAt);
			this.render();
		}
		
		public function get lookAt():Number3D{
			return this._lookAt;
		}
		
		public function set lookAt(value:Number3D):void{
			this._lookAt = value;
			this.view.camera.lookAt(value);
		}
		
		public function get showGrid():Boolean{
			return this._showGrid;
		}
		
		public function set showGrid(value:Boolean):void{
			this._showGrid = value;
			this.invalidateDisplayList();
		}
		
		override public function addChild(child:DisplayObject):DisplayObject{
			this.create3DView();
			if(child.hasOwnProperty("object3D")){
				this._view.scene.addChild(child["object3D"]);
			}
			return super.addChild(child);
		}
		
		private function create3DView():void{
			if(this._view == null){
				this._view = new away3d.containers.View3D();
				this._view.camera.lookAt(new Number3D(0,0,0));
				this.rawChildren.addChild(this._view);
			}
		}
		
		protected function addDebugElements(event:Event = null):void{
			this.wire = new WirePlane({material:"white", width:this.width, height:this.height,segments:20});
			this.vline = new LineSegment(); 
			this.vline.start = new Vertex(0,-this.height,0);
			this.vline.end = new Vertex(0,this.height,0);
			this.vline.material["color"] = 0xFF0000;
	 		this.vline.material["width"] = 2;

	        this.hline = new LineSegment();
			this.hline.start = new Vertex(-this.width,0,0);
			this.hline.end = new Vertex(this.width,0,0);
			this.hline.material["color"] = 0x00FF00;
 			this.hline.material["width"] = 2;
 			
 			this.view.scene.addChild(this.wire);
			this.view.scene.addChild(this.vline);
			this.view.scene.addChild(this.hline);
			
			this.wire.visible = this.showGrid;
			this.hline.visible = this.showGrid;
			this.vline.visible = this.showGrid;
				
			this.gridComplete = true;
			this.render();
		}
		
		override protected function createChildren():void{
			super.createChildren();
			this.create3DView();
			this.render();
			
			this.horizontalScrollPolicy = ScrollPolicy.OFF;
			this.verticalScrollPolicy = ScrollPolicy.OFF;
			this.addEventListener(FlexEvent.CREATION_COMPLETE, this.addDebugElements);
		}
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			
			if(this.view != null){
				this.view.x = this.width/2;
				this.view.y = this.height/2;
				
				if(this.autoRender){
					this.render();
				}
				
				for(var i:int=0;i<this.numChildren;i++){
					this.getChildAt(i)["invalidateDisplayList"]();
				}
			}
			
			if(this.gridComplete){
				this.wire.visible = this.showGrid;
				this.hline.visible = this.showGrid;
				this.vline.visible = this.showGrid;
				this.render();
			}
			
			this.scrollRect = new Rectangle(0,0,unscaledWidth, unscaledHeight);
		}
	}
}